<script setup>
import { reqHasTradeMark, reqSpuImageList, reqHasSaleAttr,reqFileUpload,reqAddOrUpdateSpu,reqHasSaleAttrValue } from '@/api/product/spu'
import { ref,computed,nextTick,reactive } from 'vue'
import { ElMessage} from 'element-plus'

let $emit = defineEmits(['changeScene'])  // 获取父组件绑定过来的事件

let allTradeMark = ref([])  // 所有品牌信息
let imageList = ref([])  // 单个品牌下的图片列表
let newImageList = ref([]) // 保存用户修改后的图片列表
let saleAttr = ref([])  // 收集单个品牌已有的销售属性
let allSaleAttr = ref([])  // 所有销售属性类型
let SpuParams = ref({
    "id":0,
    "category_id": null,
    "description": "",
    "spuImageList": [],
    "spuName":"",
    "spuSaleAttrList":[],
    "tmId":null,
})
let dialogVisible = ref()  // 对话框的显示与隐藏
let dialogImageUrl = ref("")  // 对话框预览图片的地址
let saleAttrIdAndName=ref('')  // 收集还未选择的销售属性的id和属性名
let attrInptArr=ref([])  // 用来获取属性输入框实例


// 点击取消按钮，触发事件，触发父组件绑定过来的事件，也就是运行父组件绑定的方法
const cancel = () => {
    $emit('changeScene', {flag:0,params:"update"})  // 触发父组件绑定过来的事件,参数1是事件名，参数2是参数
}

// 获取数据,父组件点击编辑按钮时，触发这个函数
const initHasSpuData = (spu) => {
    // 清空上一次的数据
    imageList.value=[]  // 清空图片列表
    saleAttr.value = []  // 清空属性列表
    newImageList.value = []

    // 收集spu已有的数据
    Object.assign(SpuParams.value,{
        "id":spu.id,
        "category_id": spu.category_id,
        "description": spu.description,
        "spuImageList": [],
        "spuName":spu.name,
        "spuSaleAttrList":[],
        "tmId":spu.trademark_id,
        "is_system":spu.issystem,
    })
    let c3Id = spu.category_id
    //row 即为父组件传过来的SPU对象
    // 获取指定分类下的全部品牌数据
    reqHasTradeMark(c3Id).then(res => {
        allTradeMark.value = res.data.data;
    })
    // 获取SPU销售属性
    reqHasSaleAttr(c3Id).then(res => {
        allSaleAttr.value = res.data.data
    })
    // 获取SPU图片列表
    reqSpuImageList(spu.id).then(res => {
        if(res.data.code==200){
            imageList.value = res.data.data
            // console.log(res.data.data);
        }else{
            ElMessage({
                type:'error',
                message:'获取图片失败，'+res.data.msg
            })
        }
    })
    
    reqHasSaleAttrValue(spu.id).then(res => {
        if(res.data.code==200){
            saleAttr.value = res.data.data
        }else{
            ElMessage({
                type:'error',
                message:'获取属性值失败，'+res.data.msg
            })
            
        }
    })
    // reqAllSaleAttr().then(res => {
    //     allSaleAttr.value = res.data.data
    // })
}

// 上传图片前执行的方法，可以手动调用
const handlerUpload = (fileList)=>{
    // 判断文件类型和大小是否符合要求
    for (let file of fileList){
        // 只检测刚刚上传的图片 file.status=="ready" 表示准备好上传的图片
        if(file.status=="ready"){
            if(file.raw.type=='image/png'||file.raw.type=='image/jpeg'||file.raw.type=='image/gif'){
                if(file.raw.size/1024/1024<5){
                    
                }else{
                    ElMessage({
                        type:'error',
                        message:file.raw.name + '-大小超过了5m，只能上传小于5m的图片'
                    })
                    return false
                }
            }else{
                ElMessage({
                    type:'error',
                    message:file.raw.name + '格式不符合要求，只能上传png、jpg、gif格式的图片'
                })
                return false
            }
        }
        
    }
    return true
}

// 用户添加spu图片时触发的方法
const fileChange = (file)=>{
    console.log('图片发生改变');
    console.log(file);
}

// 自定义上传图片方法
const fileUpload = async (fileList)=>{
    console.log('上传文件');
    const formData = new FormData();
    fileList.forEach(item=>{
        if(item.raw){
            formData.append('file', item.raw);
        }
    })
    if(formData.getAll('file').length==0){
        // 没有需要上传的文件，直接返回
        return
    }
    let res = await reqFileUpload(formData)
    if(res.data.code==200){
        newImageList.value = res.data.data
    }
    
    // await http.post('trademark/file_upload/', formData, {
    //     headers: {
    //         'Content-Type': 'multipart/form-data'
    //     },
    //     params:trademarkParams
    // }).then(res => {
    //     if(res.data.code==200){
    //         // 保存图片地址，data[0]?.logo 加个问号？是防止报错，只有当data[0]存在时才会执行后面的取值操作
    //         trademarkParams.logoUrl = res.data.data[0]?.logo
    //         // return res.data.data[0]?.logo
    //         // formRef.value.clearValidate('logoUrl')
    //         // return 'ok'
    //     }else{
    //         ElMessage({
    //             type:'error',
    //             message:'logo上传失败，'+res.data.msg
    //         })
    //         return Promise.reject(new Error(res.data.msg))
    //     }
        
    // })

    return
    reqFileUpload(config).then(res=>{
        // 把上传的图片保存到图片列表imageList中
        // 这里之所以不用push的方式，是因为 elemnt-plus的 el-upload组件会自动把上传的文件添加到文件列表中，所以这里只需要修改url即可
        imageList.value[imageList.value.length-1]['url']=res.data.data.imgUrl
    })
}
// 图片墙预览
const handlePictureCardPreview = (file)=>{
    dialogVisible.value = true
    dialogImageUrl.value=file.url
}
// 图片墙删除时触发的函数，elment-plus组件会自动从绑定的imageList列表中删除图片
const handleRemove = ()=>{
    console.log(imageList.value);
}
// 删除属性值
const handleCloseTag = (row,index)=>{
    row.attr_value_list.splice(index, 1)
}

// 计算当前spu还未拥有的销售属性
let unSelectSaleAttr = computed(()=>{
    // 过滤出还未拥有的销售属性
    let unSelectAttr = allSaleAttr.value.filter(item=>{
        return saleAttr.value.every(item1=>{
            return item.name != item1.sale_attr_name
        })
    })
    return unSelectAttr
})
// 点击添加属性触发的方法
const addSaleAttr = ()=>{
    let [sale_attr_id,sale_attr_name] = saleAttrIdAndName.value.split(':')
    // 添加一个新的属性
    let newSaleAttr = {
        sale_attr_id,
        sale_attr_name,
        attr_value_list:[]
    }
    saleAttr.value.push(newSaleAttr)
    saleAttrIdAndName.value = ''
}
// 属性值添加按钮点击事件
const toEdit=(row,$index)=>{
    row.flage=true  // 点击属性值添加按钮时，显示input输入框
    row.attr_value=''
    // 需要等组件渲染后才能拿到组件的实例
    nextTick(()=>{
        attrInptArr.value[$index].focus()  // 让input输入框获得焦点
    })
}
// 表单元素失去焦点时触发的事件
const toLook = (row)=>{
    // 收集属性id和属性值
    let {sale_attr_id,attr_value} = row
    row.flage=false  // 切换成添加按钮
    // 判断数据是否合理
    if(attr_value.trim()==''){
        ElMessage({
            type:'error',
            message:'属性值不能为空'
        })
        return
    }

    // 判断属性值是否已存在
    let repeat = row.attr_value_list.find(item=>{
        return item.value==attr_value
    })
    if(repeat){
        ElMessage({
            type:'error',
            message:'属性值已存在'
        })
        return
    }

    // 整理成服务器需要的格式
    let newSaleAttrValue={
        sale_attr_id,
        value:attr_value
    }

    row.attr_value_list.push(newSaleAttrValue)  // 添加属性值到属性值列表中
    
}

// 保存数据
const save = async ()=>{
    // 检测用户上传的文件是否合理
    if(!handlerUpload(imageList.value)){
        // 文件不符合要求，停止执行
        return
    }
    // 上传图片,并拿到url地址,然后再提交SPU信息
    await fileUpload(imageList.value)

    // 收集新增的图片数据
    SpuParams.value.spuImageList = newImageList.value.map(item=>{
        return {
            name:item.name,
            url:item.url
        }
    })
    // 旧的图片数据也要传回去，后端做对比
    SpuParams.value.old_spuImageList = imageList.value

    
    // 收集销售属性的数据
    SpuParams.value.spuSaleAttrList = saleAttr.value
    // console.log(SpuParams);
    reqAddOrUpdateSpu(SpuParams.value).then(res=>{
        if(res.data.code==200){
            ElMessage({
                type:'success',
                message:SpuParams.value.id?'修改成功':'添加成功'
            })
            // 切换场景，显示spu列表
            $emit('changeScene', {flag:0,params:SpuParams.value.id?"update":"add"})
        }else{
            ElMessage({
                type:'error',
                message:SpuParams.value.id?'修改失败，' + res.data.msg:'添加失败，' + res.data.msg
            })
        }
    })
    
    // console.log(SpuParams.value);
    
}

// 添加SPU数据初始化
const initAddSpu = (c3Id)=>{
    // 清空数据
    Object.assign(SpuParams.value,{
        "id":0,
        "category_id": null,
        "description": "",
        "spuImageList": [],
        "spuName":"",
        "spuSaleAttrList":[],
        "tmId":null
    })
    //清空照片
    imageList.value = [];
    //清空销售属性
    saleAttr.value = [];
    saleAttrIdAndName.value  = '';

    // 保存三级分类的id
    SpuParams.value.category_id=c3Id
    // 获取指定分类下的全部品牌数据
    reqHasTradeMark(c3Id).then(res => {
        allTradeMark.value = res.data.data;
        // console.log(allTradeMark.value);
    })
    // 获取SPU销售属性
    reqHasSaleAttr(c3Id).then(res => {
        allSaleAttr.value = res.data.data
    })
    
   
}

// setpu里面写的属性和方法，默认对外是关闭的，需要用defineExpose对外导出
// 导出后，父组件就能拿到子组件的属性和方法了
defineExpose({ initHasSpuData,initAddSpu })

</script>

<template>
    <div>
        <el-form label-width="100px">
            <el-form-item label="SPU名称"> <el-input placeholder="请输入SPU名称" v-model="SpuParams.spuName"></el-input> </el-form-item>
            <el-form-item label="SPU品牌">
                <el-select v-model="SpuParams.tmId">
                    <el-option :label="item.name" v-for="(item,index) in allTradeMark" :key="item.id" :value="item.id"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="SPU描述">
                <el-input type="textarea" placeholder="请输入SPU描述" v-model="SpuParams.description"></el-input>
            </el-form-item>
            <el-form-item label="SPU图片">
                <el-upload v-model:file-list="imageList" action="#" multiple
                    list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                    :http-request="fileUpload" :before-upload="handlerUpload" :auto-upload="false" :on-change="fileChange">
                    <el-icon>
                        <Plus />
                    </el-icon>
                </el-upload>

                <el-dialog v-model="dialogVisible">
                    <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%;height: 100%;" />
                </el-dialog>
            </el-form-item>

            <el-form-item label="SPU销售属性">
                <!-- 展示销售属性的下拉菜单 -->
                <el-select :placeholder="unSelectSaleAttr.length?`还未选择的属性有${unSelectSaleAttr.length}个`:'无'" v-model="saleAttrIdAndName">
                    <el-option v-for="(item,index) in unSelectSaleAttr" :label="item.name" :key="item.id" :value="`${item.id}:${item.name}`"></el-option>
            
                </el-select>
                <el-button :disabled="saleAttrIdAndName?false:true" type="primary" icon="Plus" style="margin-left:10px ;" @click="addSaleAttr">添加属性</el-button>

                <!-- 展示销售属性 用table组件 -->
                <el-table border style="margin: 10px 0;" :data="saleAttr">
                    <el-table-column label="序号" type="index" width="80px"></el-table-column>
                    <el-table-column label="销售属性" width="120px" prop="sale_attr_name"></el-table-column>
                    <el-table-column label="销售属性值">
                        <template #="{row,$index}">
                            <el-tag v-for="(item,index) in row.attr_value_list" :key="index" class="mx-1" closable
                            :disable-transitions="false" @close="handleCloseTag(row,index)" style="margin-right: 5px;">
                            {{ item.value }}
                            </el-tag>
                            <el-input v-model="row.attr_value" @blur="toLook(row)" v-if="row.flage==true" placeholder="请输入属性值" size="small" 
                            style="width:100px" :ref="attrInpt=>attrInptArr[$index]=attrInpt"></el-input>
                            <el-button v-else size="small" type="primary" icon="Plus" @click="toEdit(row,$index)"></el-button>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="100px">
                        <template #="{row,$index}">
                            <el-button size="small" type="primary" icon="Delete" @click="saleAttr.splice($index,1)"></el-button>
                        </template>
                    </el-table-column>

                </el-table>

            </el-form-item>

            <el-form-item>
                <el-button type="primary" @click="save" :disabled="saleAttr.length>0?false:true">保存</el-button>
                <el-button type="primary" @click="cancel()">取消</el-button>
            </el-form-item>

        </el-form>
    </div>
</template>

<style scoped lang="scss"></style>